package com.jsmtr.rms.service.impl;

import com.jsmtr.rms.dao.DaoService;
import com.jsmtr.rms.dao.impl.DaoServiceImpl;
import com.jsmtr.rms.entity.BaseUser;
import com.jsmtr.rms.entity.LimitRequest;
import com.jsmtr.rms.entity.QuestionBank;
import com.jsmtr.rms.entity.ResponseBuilder;
import com.jsmtr.rms.service.ITopicService;
import com.jsmtr.rms.service.IUtilService;
import com.jsmtr.rms.utils.RightInterceptor;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wyh
 */
@Service
public class TopicServiceImpl implements ITopicService {
    @Autowired
    DaoService dao;

    @Override
    @SuppressWarnings({"unchecked","rawtypes"})
    @Transactional(rollbackFor = Exception.class)
    public String getTopoicList(LimitRequest lRequest) {
        try {
            Map<String, Object> params = new HashMap<>(6);
            Map<String, Object> search = lRequest.getSearch();
            String hql = "select qb,know.name from QuestionBank qb, KnowManage know where know.id=qb.kid ";
            String countHql = "select count(*) from QuestionBank qb, KnowManage know where know.id=qb.kid ";
            String topicTypeSuffix = " and qb.type=:topicType";
            String positionSuffix = " and qb.path=:path";
            String knowledgeNameSuffix = "and qb.kid=:knowledgeName";
            String topicDifficultySuffix = " and qb.difficulty=:topicDifficulty";
            String topicStateSuffix = " and qb.state=:topicState";
            String orderSuffix = " order by ";
            int curPage = lRequest.getPage();
            int pageSize = lRequest.getLimit();

            if (search != null) {
                String topicType = (String)search.get("type");
                if (StringUtils.isNotBlank(topicType)) {
                    hql += topicTypeSuffix;
                    countHql += topicTypeSuffix;
                    params.put("topicType", topicType);
                }
                String position = (String)search.get("path");
                if (StringUtils.isNotBlank(position)) {
                    hql += positionSuffix;
                    countHql += positionSuffix;
                    params.put("path", position);
                }
                String knowledgeName = (String)search.get("kid");
                if (StringUtils.isNotBlank(knowledgeName)) {
                    hql += knowledgeNameSuffix;
                    countHql += knowledgeNameSuffix;
                    params.put("knowledgeName", knowledgeName);
                }
                String topicDifficulty = (String)search.get("difficulty");
                if (StringUtils.isNotBlank(topicDifficulty)) {
                    hql += topicDifficultySuffix;
                    countHql += topicDifficultySuffix;
                    params.put("topicDifficulty", topicDifficulty);
                }                
                String topicState = (String)search.get("state");
                if (StringUtils.isNotBlank(topicState)) {
                    hql += topicStateSuffix;
                    countHql += topicStateSuffix;
                    params.put("topicState", topicState);
                }
            }


            String orderKey = lRequest.getOrderKey();
            String orderType = lRequest.getOrderType();
            if (orderKey != null && orderType != null) {
                hql += orderSuffix + orderKey + " " + orderType;
            }

            long total = (Long)dao.findUnique(countHql, params);
            List result = dao.findLimit(hql, params, (curPage - 1) * pageSize, pageSize);
            result = (List)result.stream().map(item-> {
                JSONObject jsonObject = JSONObject.fromObject(((Object[])item)[0]);
                jsonObject.put("kname", ((Object[])item)[1]);
                return jsonObject;
            }).collect(Collectors.toList());
            JSONArray data = JSONArray.fromObject(result);
            ResponseBuilder builder = new ResponseBuilder();
            return builder.setData(data.toString()).setPage(curPage, (int)total).build();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    @SuppressWarnings("rawtypes")
    @Transactional(rollbackFor = Exception.class)
    public boolean addTopic(QuestionBank questionBank, HttpServletRequest request) {
        try {
            String hql = "from QuestionBank where kid=:kid and data=:data and path=:path";
            Map<String, Object> params = new HashMap<>(3);
            params.put("kid", questionBank.getKid());
            params.put("data", questionBank.getData());
            params.put("path", questionBank.getPath());
            List fnd = dao.find(hql, params);
            if (fnd != null && fnd.size() > 0) {
                throw new Exception();
            }
            BaseUser baseUser = (BaseUser)request.getSession().getAttribute(RightInterceptor.SEESION_MEMBER);
            questionBank.setModifyDate(new Date());
            questionBank.setModifyName(baseUser.getUname());
            //默认开启
            questionBank.setState(ENABLED);
            if (StringUtils.isBlank(questionBank.getName())) {
                questionBank.setName(questionBank.getData());
            }
            dao.add(questionBank);
            return true;
        } catch (Exception exception) {
            exception.printStackTrace();
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addTopicFindKid(QuestionBank questionBank, HttpServletRequest request) {
        try {
            String hql = "select id from KnowManage where name=:name";
            Map<String, Object> params = new HashMap<>(1);
            params.put("name",questionBank.getKid());
            String kid = (String)dao.findFirst(hql, params);
            if (StringUtils.isEmpty(kid)) {
                throw new Exception();
            }
            questionBank.setKid(kid);

            BaseUser baseUser = (BaseUser)request.getSession().getAttribute(RightInterceptor.SEESION_MEMBER);
            questionBank.setModifyDate(new Date());
            questionBank.setModifyName(baseUser.getUname());
            //默认开启
            questionBank.setState(ENABLED);
            dao.add(questionBank);
            return true;
        } catch (Exception exception) {
            exception.printStackTrace();
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editTopic(QuestionBank questionBank, HttpServletRequest request) {
        try {
            BaseUser baseUser = (BaseUser)request.getSession().getAttribute(RightInterceptor.SEESION_MEMBER);
            questionBank.setModifyName(baseUser.getUname());
            questionBank.setModifyDate(new Date());
            if (StringUtils.isBlank(questionBank.getName())) {
                questionBank.setName(questionBank.getData());
            }
            dao.update(questionBank);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTopic(String id) {
        try {
            String hql = "delete QuestionBank where id=:id";
            Map<String, Object> params = new HashMap<>(1);
            params.put("id", id);
            int infected = dao.executeHQL(hql, params);
            return infected == 1;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public QuestionBank seeTopic(String id) {
        try {
            return (QuestionBank)dao.get(QuestionBank.class, id);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    final public static String DISABLED = "disabled";
    final public static String ENABLED = "enabled";
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editenableTopic(String id, Boolean state, HttpServletRequest request) {
        try {
            QuestionBank qb = (QuestionBank)dao.get(QuestionBank.class, id);
            BaseUser baseUser = (BaseUser)request.getSession().getAttribute(RightInterceptor.SEESION_MEMBER);
            qb.setModifyDate(new Date());
            qb.setModifyName(baseUser.getUname());
            qb.setState(state?ENABLED:DISABLED);
            dao.update(qb);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 已被addTopicFindKid代替
     */
    @Deprecated
    @Override
    public boolean importTopic() {
        return false;
    }

    @Override
    @SuppressWarnings("rawtypes")
    public List getKids() {
        try {
            String sql = "select distinct qb.kid,know.NAME from QUESTIONBANK qb left join KNOWMANAGE know on qb.kid=know.id";
            return dao.executeSQLQuery(sql);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    @SuppressWarnings("rawtypes")
    public List getPaths() {
        try {
            String sql = "select distinct path from questionbank";
            return dao.executeSQLQuery(sql);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void setDao(DaoService dao) {
        this.dao = dao;
    }
}
